using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using BaseAmd.BaseDevice;
using Catastrophe.Common;
using SiemensAmd.Mmt.Amd;
using SqlSugar;
using SqlSugarEx;
using SqlSugarEx.Config;
using SqlSugarEx.Ret;
using SqlSugarEx.Utilities;

namespace SiemensAmd.Mmt.DevQt
{
	public class ToolDeviceCacheDal
	{
		private readonly SqlSugarClientEx _dbSugar;

		private static object SyncLock = new object();

		private DbAppConfig _dbConfig;

		private ToolDeviceConfigDal _toolDeviceConfigDal;

		private Expression<Func<ToolDeviceCacheEntity, object>> _ignoreCols = (ToolDeviceCacheEntity x) => new { x.Id, x.DeviceNo, x.FMCNo, x.MasterUse, x.EdgeIndex, x.FixedLocation };

		public ToolDeviceCacheDal(DbAppConfig dbConfig)
		{
			this._dbConfig = dbConfig ?? throw new ArgumentNullException("dbConfig");
			this._dbConfig = dbConfig;
			this._dbSugar = DbUtility.GetSugar(dbConfig, isAutoCloseCon: true);
			this._toolDeviceConfigDal = new ToolDeviceConfigDal(this._dbConfig);
		}

		public List<ToolDeviceCacheUnionEntity> QueryTools(string fmcNo, string deviceNo, params int[] toolMag)
		{
			return this.QueryToolsEx<ToolDeviceCacheUnionEntity, ToolDeviceCacheEntity, ToolDeviceConfigEntity, ToolDeviceSuppEntity, ToolMagConfigEntity>(fmcNo, deviceNo, toolMag);
		}

		public List<Tunion> QueryToolsEx<Tunion, T1, T2, T3, T4>(string fmcNo, string deviceNo, params int[] toolMag) where Tunion : ToolDeviceCacheUnionEntity where T1 : ToolDeviceCacheEntity where T2 : ToolDeviceConfigEntity where T3 : ToolDeviceSuppEntity where T4 : ToolMagConfigEntity
		{
			lock (ToolDeviceCacheDal.SyncLock)
			{
				SqlSugarClientEx sugar = DbUtility.GetSugar(this._dbConfig, isAutoCloseCon: true);
				ISugarQueryable<T1, T2, T3, T4> sugarQueryable = sugar.Queryable((T1 a, T2 b, T3 c, T4 d) => new JoinQueryInfos(JoinType.Left, a.FMCNo == b.FMCNo && a.DeviceNo == b.DeviceNo && a.ToolInMag == b.ToolInMag && a.ToolInPlace == b.ToolInPlace, JoinType.Left, a.FMCNo == c.FMCNo && a.DeviceNo == c.DeviceNo && a.ToolNo == c.ToolNo, JoinType.Left, a.FMCNo == d.FMCNo && a.DeviceNo == d.DeviceNo && a.ToolInMag == d.MagNo)).WhereIF(!string.IsNullOrWhiteSpace(fmcNo), (T1 a) => a.FMCNo == fmcNo).WhereIF(!string.IsNullOrWhiteSpace(deviceNo), (T1 a) => a.DeviceNo == deviceNo);
				int[] array = toolMag;
				ISugarQueryable<Tunion> sugarQueryable2 = (from a in sugarQueryable.WhereIF(array != null && array.Length != 0, (T1 a) => SqlFunc.ContainsArray(toolMag, a.ToolInMag)).OrderBy((T1 a) => a.ToolInMag, OrderByType.Desc)
					orderby a.ToolInPlace
					orderby a.ToolIdent
					orderby a.DuploNo
					orderby a.EdgePosition
					orderby a.DNo
					select a).Select<Tunion>();
				KeyValuePair<string, List<SugarParameter>> keyValuePair = sugarQueryable2.ToSql();
				return sugarQueryable2.ToList();
			}
		}

		public List<ToolEntitySimpleEx> ToolSimpleCombine(string fmcNo, string deviceNo, List<ToolEntitySimple> list)
		{
			if (deviceNo == null)
			{
				throw new ArgumentNullException("deviceNo");
			}
			if (list == null)
			{
				throw new ArgumentNullException("list");
			}
			if (list.Count == 0)
			{
				return new List<ToolEntitySimpleEx>();
			}
			List<ToolDeviceCacheUnionEntity> source = (from x in this.QueryTools(fmcNo, deviceNo)
				where x.ToolInMag == 1 || x.ToolInMag == 9998
				select x).ToList();
			List<ToolEntitySimpleEx> list2 = new List<ToolEntitySimpleEx>();
			foreach (ToolEntitySimple item in list)
			{
				int? num = null;
				if (!item.IsEmpty)
				{
					num = (from x in source
						where x.ToolIdent == item.ToolIdent
						where x.DuploNo == item.DuploNo
						where x.ToolInPlace == item.ToolInPlace
						select x).FirstOrDefault()?.ToolId;
				}
				ToolEntitySimpleEx toolEntitySimpleEx = DataConverter.DeepCopy<ToolEntitySimple, ToolEntitySimpleEx>(item);
				if (num.HasValue)
				{
					toolEntitySimpleEx.ToolId = num.Value;
				}
				list2.Add(toolEntitySimpleEx);
			}
			return list2;
		}

		public List<ToolPalceDataExEntity> ToolPlaceDataCombine(string fmcNo, string machineNo, List<ToolPalceDataEntity> list, int magNo = 1)
		{
			if (machineNo == null)
			{
				throw new ArgumentNullException("machineNo");
			}
			if (list == null)
			{
				throw new ArgumentNullException("list");
			}
			if (list.Count == 0)
			{
				return new List<ToolPalceDataExEntity>();
			}
			List<ToolDeviceCacheUnionEntity> source = (from x in this.QueryTools(fmcNo, machineNo)
				where x.ToolInMag == 1
				select x).ToList();
			List<ToolPalceDataExEntity> list2 = new List<ToolPalceDataExEntity>();
			foreach (ToolPalceDataEntity item in list)
			{
				ToolPalceDataExEntity entity = DataConverter.DeepCopy<ToolPalceDataEntity, ToolPalceDataExEntity>(item);
				ToolDeviceCacheUnionEntity toolDeviceCacheUnionEntity = source.FirstOrDefault((ToolDeviceCacheUnionEntity x) => x.DeviceNo == machineNo && x.ToolInMag == magNo && x.ToolInPlace == entity.ToolInPlace);
				if (toolDeviceCacheUnionEntity != null)
				{
					entity.PlaceValid = toolDeviceCacheUnionEntity.PlaceValid;
					entity.LengthMin = toolDeviceCacheUnionEntity.LengthMin;
					entity.LengthMax = toolDeviceCacheUnionEntity.LengthMax;
					entity.RadiusMin = toolDeviceCacheUnionEntity.RadiusMin;
					entity.RadiusMax = toolDeviceCacheUnionEntity.RadiusMax;
				}
				list2.Add(entity);
			}
			return list2;
		}

		public int UpdatePlaceLimit(string machineNo, int magNo, int location, bool valid, float lengthMin, float lengthMax, float radiusMin, float radiusMax)
		{
			int num = (from x in this._dbSugar.Updateable<ToolDeviceConfigEntity>().SetColumns((ToolDeviceConfigEntity x) => new ToolDeviceConfigEntity
				{
					PlaceValid = valid,
					LengthMin = lengthMin,
					LengthMax = lengthMax,
					RadiusMin = radiusMin,
					RadiusMax = radiusMax
				})
				where x.DeviceNo == machineNo
				where x.ToolInMag == magNo
				where x.ToolInPlace == location
				select x).ExecuteCommand();
			if (num == 0)
			{
				num = this._dbSugar.Insertable(new ToolDeviceConfigEntity
				{
					DeviceNo = machineNo,
					ToolInMag = magNo,
					ToolInPlace = location,
					PlaceValid = valid,
					LengthMin = lengthMin,
					LengthMax = lengthMax,
					RadiusMin = radiusMin,
					RadiusMax = radiusMax
				}).ExecuteCommand();
			}
			return num;
		}

		public void ToolTransCommit(Dictionary<ToolDeviceCacheUnionEntity, DbCompareRetEnum> dic, ToolInterfaceTypeEnum toolInterfaceType)
		{
			SqlSugarClientEx sugar = DbUtility.GetSugar(this._dbConfig, isAutoCloseCon: true);
			try
			{
				sugar.BeginTran();
				(from x in sugar.Deleteable<ToolDeviceCacheEntity>()
					where SqlFunc.IsNullOrEmpty(x.DeviceNo) || (!x.IsEmpty && SqlFunc.IsNullOrEmpty(x.ToolIdent))
					select x).ExecuteCommand();
				ToolDeviceCacheUnionEntity item;
				foreach (ToolDeviceCacheUnionEntity key in dic.Keys)
				{
					item = key;
					switch (dic[item])
					{
					case DbCompareRetEnum.Add:
						sugar.Insertable((ToolDeviceCacheEntity)item).ExecuteCommand();
						break;
					case DbCompareRetEnum.Delete:
						switch (toolInterfaceType)
						{
						case ToolInterfaceTypeEnum.QtDev:
							if (!item.FixedLocation)
							{
								(from x in sugar.Deleteable<ToolDeviceCacheEntity>()
									where x.Id == item.Id
									select x).ExecuteCommand();
								break;
							}
							(from x in sugar.Updateable(new ToolDeviceCacheEntity
								{
									IsEmpty = true
								}).IgnoreColumns(this._ignoreCols)
								where x.Id == item.Id
								where !x.IsEmpty
								select x).ExecuteCommand();
							break;
						case ToolInterfaceTypeEnum.Mmt:
							(from x in sugar.Deleteable<ToolDeviceCacheEntity>()
								where x.Id == item.Id
								select x).ExecuteCommand();
							break;
						}
						break;
					case DbCompareRetEnum.Update:
						switch (toolInterfaceType)
						{
						case ToolInterfaceTypeEnum.QtDev:
							item.IsEmpty = false;
							(from x in sugar.Updateable((ToolDeviceCacheEntity)item).IgnoreColumns(this._ignoreCols)
								where x.Id == item.Id
								select x).ExecuteCommand();
							break;
						case ToolInterfaceTypeEnum.Mmt:
							if (item.IsEmpty)
							{
								int num = (from x in sugar.Updateable((ToolDeviceCacheEntity)item).IgnoreColumns(this._ignoreCols)
									where x.DeviceNo == item.DeviceNo && x.ToolInPlace == item.ToolInPlace
									select x).ExecuteCommand();
								break;
							}
							(from x in sugar.Updateable((ToolDeviceCacheEntity)item).IgnoreColumns(this._ignoreCols)
								where x.DeviceNo == item.DeviceNo
								where x.ToolNo == item.ToolNo
								where x.DNo == item.DNo
								select x).ExecuteCommand();
							break;
						}
						break;
					}
				}
				sugar.CommitTran();
			}
			catch (Exception)
			{
				sugar.RollbackTran();
			}
		}

		public DbOperateRet CreateMag(string fmcNo, string deviceNo, Dictionary<int, int> dicMagCapacity, int maxEdgeCount, bool clearAll = false)
		{
			if (deviceNo == null)
			{
				throw new ArgumentNullException("deviceNo");
			}
			DbOperateRet dbOperateRet = new DbOperateRet();
			SqlSugarClientEx sugar = DbUtility.GetSugar(this._dbConfig, isAutoCloseCon: true);
			if (clearAll)
			{
				(from x in sugar.Deleteable<ToolDeviceCacheEntity>()
					where x.DeviceNo == deviceNo
					select x).ExecuteCommand();
				this._toolDeviceConfigDal.Clear();
			}
			this._toolDeviceConfigDal.CreateMagConfig(fmcNo, deviceNo, dicMagCapacity);
			List<int> deletePkBuff = new List<int>();
			List<ToolDeviceCacheEntity> addEntities = new List<ToolDeviceCacheEntity>();
			int num = 0;
			List<ToolDeviceCacheEntity> source = (from x in sugar.Queryable<ToolDeviceCacheEntity>()
				where x.DeviceNo == deviceNo
				orderby x.ToolInPlace
				select x).ToList();
			Action<int, int, int, int, int> action = delegate(int magNo, int capacity, int maxEdgeCount, int startToolPlace, int startEdgePos)
			{
				for (int k = startToolPlace; k < capacity + startToolPlace; k++)
				{
					for (int l = startEdgePos; l < maxEdgeCount + startEdgePos; l++)
					{
						addEntities.Add(new ToolDeviceCacheEntity
						{
							ToolInPlace = k,
							ToolInMag = magNo,
							FMCNo = fmcNo,
							DeviceNo = deviceNo,
							TimeStamp = DateTime.Parse(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")),
							EdgeIndex = l,
							IsEmpty = true,
							FixedLocation = true
						});
					}
				}
			};
			List<int> magNoList = new List<int>();
			foreach (int magNo2 in dicMagCapacity.Keys)
			{
				magNoList.Add(magNo2);
				int num2 = dicMagCapacity[magNo2];
				int num3 = num2 * maxEdgeCount;
				List<ToolDeviceCacheEntity> magEntities = source.Where((ToolDeviceCacheEntity x) => x.ToolInMag == magNo2).ToList();
				if (magEntities.Count == 0)
				{
					action(magNo2, num2, maxEdgeCount, 1, 1);
					continue;
				}
				Func<int, int, List<ToolDeviceCacheEntity>> func = (int toolPlace, int edgeIndex) => (from x in magEntities
					where x.ToolInPlace == toolPlace
					where x.EdgeIndex == edgeIndex
					select x).ToList();
				for (int i = 1; i <= num2; i++)
				{
					for (int j = 1; j <= maxEdgeCount; j++)
					{
						List<ToolDeviceCacheEntity> list = func(i, j);
						if (list.Count != 1)
						{
							if (list.Count == 0)
							{
								action(magNo2, 1, 1, i, j);
								continue;
							}
							action(magNo2, 1, 1, i, j);
							foreach (ToolDeviceCacheEntity item in list)
							{
								item.RowState = DbCompareRetEnum.Delete;
								deletePkBuff.Add(item.Id);
							}
						}
						else
						{
							list.First().RowState = DbCompareRetEnum.None;
						}
					}
				}
				List<ToolDeviceCacheEntity> list2 = magEntities.Where((ToolDeviceCacheEntity x) => !x.RowState.HasValue && x.FixedLocation).ToList();
				if (list2.Count > 0)
				{
					deletePkBuff.AddRange(list2.Select((ToolDeviceCacheEntity x) => x.Id));
				}
			}
			List<ToolDeviceCacheEntity> list3 = source.Where((ToolDeviceCacheEntity x) => !magNoList.Contains(x.ToolInMag) && x.FixedLocation).ToList();
			if (list3.Count > 0)
			{
				deletePkBuff.AddRange(list3.Select((ToolDeviceCacheEntity x) => x.Id));
			}
			try
			{
				if (deletePkBuff.Count == 0 && addEntities.Count == 0)
				{
					dbOperateRet.Success = true;
					return dbOperateRet;
				}
				sugar.BeginTran();
				if (deletePkBuff.Count > 0)
				{
					num += (from x in sugar.Deleteable<ToolDeviceCacheEntity>()
						where SqlFunc.ContainsArray(deletePkBuff, x.Id)
						select x).ExecuteCommand();
				}
				if (addEntities.Count > 0)
				{
					num += sugar.Insertable(addEntities).ExecuteCommand();
				}
				sugar.CommitTran();
				dbOperateRet.Success = num > 0;
				return dbOperateRet;
			}
			catch (Exception ex)
			{
				dbOperateRet.Message = ex.ToString();
				return dbOperateRet;
			}
		}
	}
}
